package be.destin.abdera;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.apache.abdera.protocol.server.CollectionInfo;
import org.apache.abdera.protocol.server.RequestContext;
import org.apache.abdera.protocol.server.RequestContext.Scope;
import org.apache.abdera.protocol.server.WorkspaceInfo;
import org.apache.abdera.protocol.server.impl.DefaultWorkspaceManager;
import org.apache.abdera.protocol.server.impl.SimpleWorkspaceInfo;
import org.apache.abdera.protocol.server.provider.basic.BasicProvider;
import org.apache.abdera.protocol.server.servlet.ServletRequestContext;
import org.apache.cayenne.ObjectContext;
import org.apache.cayenne.access.DataContext;
import org.apache.cayenne.configuration.CayenneRuntime;
import org.apache.cayenne.configuration.web.WebUtil;

import be.destin.cayenne.CayenneHelpers;
import be.destin.memolog.UsageLogger;
import be.destin.memolog.UsageMode;
import be.destin.records.UsageManager;
import be.destin.skos.core.Concept;
import be.destin.skos.core.SkosManager;

public class MemoProvider extends AbstractCorrectedWorkspaceProvider {

	static final String aggregateDataMode = "memo";
	
	//static final MemoProvider[] memoWorkspaces = new MemoProvider[UsageMode.values().length];
	
    SkosManager skosManager;
    UsageMode mode = null;

	/**
	 * 
	 */
	public MemoProvider(String host, String base, WorkspaceInfo wi, SkosManager skosManager) {
		super();
		this.skosManager = skosManager;
		this.init (host, base, wi);
		if (base.equalsIgnoreCase(aggregateDataMode)) {
			this.mode = null;
		} else {
			int pDot = base.indexOf('.');
			if (pDot >= 0) base = base.substring(0,pDot); 
			this.mode = UsageMode.valueOf(base.toUpperCase());
			//memoWorkspaces[this.mode.ordinal()] = this; // To be able to generate links toward other modes
		}
	}

    @Override
    public MemoCollectionAdapter getCollectionAdapter(RequestContext request) {
        //String path = request.getContextPath() + request.getTargetPath();
        // Typically this happens when a Resolver wants to override the CollectionAdapter being used
        MemoCollectionAdapter ca = (MemoCollectionAdapter)request.getAttribute(Scope.REQUEST, DefaultWorkspaceManager.COLLECTION_ADAPTER_ATTRIBUTE);
        if (ca != null) {
            return ca;
        }
        String coll = request.getTarget().getParameter(BasicProvider.PARAM_FEED);
        if (coll == null || coll.isEmpty()) return null;

        for (CollectionInfo ci : this.workspace.getCollections(request)) {
        	String ciColl = ((MemoCollectionAdapter)ci).getHref();
//log.error(ci.getHref(request)+",col="+ciColl+" = "+coll);
        	if (coll.equalsIgnoreCase(ciColl)) {
        		/* Caches access to the CollectionAdapter */
        		request.setAttribute( DefaultWorkspaceManager.COLLECTION_ADAPTER_ATTRIBUTE, ci);
        		return (MemoCollectionAdapter)ci;
        	}
        }
        if (coll != null && !coll.isEmpty()) {
        	Concept aMemoColl = skosManager.getApplications().getConcept(coll);
        	if (aMemoColl != null) {
        		ca = new MemoCollectionAdapter(skosManager, aMemoColl, this.mode); 
        		for (WorkspaceInfo wi: this.getWorkspaces(request)) {
        			((SimpleWorkspaceInfo)wi).addCollection(ca);
        			break;
        		}
        	}
        }
        return ca;
    }

    public MemoCollectionAdapter getCollectionAdapter(RequestContext request,UsageLogger oneLogEntry) {
    	String anApp = oneLogEntry.getApplication();
    	for (CollectionInfo ci : this.workspace.getCollections(request)) {
    		if (anApp.equalsIgnoreCase(((MemoCollectionAdapter)ci).getCriteria().getAbout())) {
    			return (MemoCollectionAdapter)ci;
    		}
    	}
    	return null;
    }

    public SkosManager getSkosManager() {
		return skosManager;
	}


	public void setSkosManager(SkosManager skosManager) {
		this.skosManager = skosManager;
	}


    public MemoSearchUrlAdapter newSearchUrlAdapter() {
    	return new MemoSearchUrlAdapter(this, skosManager);
    }

	public static ObjectContext getCayenneContext(RequestContext req) {
		return DataContext.getThreadObjectContext();
	}
	
	public static UsageLogger getNewUsageLogger (RequestContext request, String applicationId, String recordId, UsageMode mode) {
		String aUser = getCurrentUser(request);
		ObjectContext aContext = getCayenneContext(request);
		UsageLogger ul = new UsageLogger(aUser,applicationId,recordId,mode);
		ul.setContext(aContext);
		return ul;
	}

	public static UsageLogger getNewUsageLogger (RequestContext request, String entryId, UsageMode mode) {
		String aUser = getCurrentUser(request);
		ObjectContext aContext = getCayenneContext(request);
		UsageLogger ul = new UsageLogger(entryId);
		ul.setUser(aUser);
		ul.setMode(mode);
		ul.setContext(aContext);
		return ul;
	}

	public UsageLogger getUsageLoggerFromURL (RequestContext request, String url, UsageMode mode) {
		String aUser = getCurrentUser(request);
		ObjectContext aContext = getCayenneContext(request);
		UsageLogger ul = new UsageLogger(aUser, null, null, mode);
		ul.setContext(aContext);
		UsageManager.fillUsageLogger(skosManager, ul, url);
		return ul;
	}
}
